package com.example.networktest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONArray
import org.xml.sax.InputSource
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserFactory
import retrofit2.Call
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.StringReader
import java.lang.StringBuilder
import java.net.HttpURLConnection
import java.net.URL
import java.util.concurrent.TimeUnit
import javax.xml.parsers.SAXParserFactory
import kotlin.concurrent.thread

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sendRequestBtn.setOnClickListener {
//            sendRequestWithHttpURLConnection()
//            sendRequestWithOkHttp()
//            sendRequestWithOkHttpAndParseXMLWithPull()
        }

        getAppDataBtn.setOnClickListener {
//            val retrofit = Retrofit.Builder()
//                .baseUrl("http://10.221.102.214")
//                .addConverterFactory(GsonConverterFactory.create())
//                .build()
//            val appService = retrofit.create(AppService::class.java)

            val appService = ServiceCreator.create<AppService>()
            appService.getAppData().enqueue(object : retrofit2.Callback<List<App>> {
                override fun onResponse(call: Call<List<App>>, response: Response<List<App>>) {
                    val list = response.body()
                    if(list != null){
                        for(app in list){
                            Log.d("MainActivity", "id is ${app.id}")
                            Log.d("MainActivity", "name is ${app.name}")
                            Log.d("MainActivity", "version is ${app.version}")
                        }
                    }
                }

                override fun onFailure(call: Call<List<App>>, t: Throwable) {
                   t.printStackTrace()
                }
            })
        }

    }

    private fun sendRequestWithHttpURLConnection() {
        thread {

            //使用HttpURLConnection
            var connection: HttpURLConnection? = null
            try {
                val url = URL("https://www.baidu.com")
                connection = url.openConnection() as HttpURLConnection
                connection.connectTimeout = 8000
                connection.readTimeout = 8000
                connection.requestMethod = "GET"
//                connection.requestMethod = "POST"
//                val dataOutputStream = DataOutputStream(connection.outputStream)
//                dataOutputStream.writeBytes("user=admin&password=1233445")
                val inputStream = connection.inputStream
                val bufferedReader = BufferedReader(InputStreamReader(inputStream))
                val stringBuilder = StringBuilder()
                bufferedReader.use {
                    bufferedReader.forEachLine {
                        stringBuilder.append(it)
                    }
                }
                showResponse(stringBuilder.toString())
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                connection?.disconnect()
            }
        }
    }


    //使用okHttp方式
//    private fun sendRequestWithOkHttp() {
//        thread {
//            try {
//                val client = OkHttpClient()
//                val request = Request.Builder()
//                    .url("https://www.baidu.com")
//                    .build()
//                val response = client.newCall(request).execute()
//                val body = response.body?.string()
//                if (body != null) {
//                    showResponse(body)
//                }
//            } catch (e: Exception) {
//                e.printStackTrace()
//            }
//        }
//    }

//    private fun sendRequestWithOkHttpAndParseXMLWithPull() {
//        thread {
//            try {
//                val okHttpClient = OkHttpClient()
//                    .newBuilder()
//                    .connectTimeout(10L, TimeUnit.SECONDS)
//                    .readTimeout(10L, TimeUnit.SECONDS)
//                    .build()
//                val request = Request.Builder()
//                    .url("http://10.221.102.214/get_data.json")
//                    .build()
//                val response = okHttpClient.newCall(request).execute()
//                val body = response.body?.string()
//                if (body != null) {
////                    parseXMLWithPull(body)
////                    parseXMLWithSAX(body)
//                    parseJSONWithJSONObject(body)
//                }
//            } catch (e: Exception) {
//                e.printStackTrace()
//            }
//        }
//    }

    private fun showResponse(str: String) {
        runOnUiThread {
            responseText.text = str
        }
    }

    private fun parseXMLWithPull(xmlData: String) {
        try {
            val factory = XmlPullParserFactory.newInstance()
            val xmlPullParser = factory.newPullParser()
            xmlPullParser.setInput(StringReader(xmlData))
            var eventType = xmlPullParser.eventType
            var id = ""
            var name = ""
            var version = ""
            while (eventType != XmlPullParser.END_DOCUMENT) {
                val nodeName = xmlPullParser.name
                when (eventType) {
                    XmlPullParser.START_TAG -> {
                        when (nodeName) {
                            "id" -> id = xmlPullParser.nextText()
                            "name" -> name = xmlPullParser.nextText()
                            "version" -> version = xmlPullParser.nextText()
                        }
                    }

                    //完成解析某个及节点
                    XmlPullParser.END_TAG -> {
                        if ("app" == nodeName) {
                            Log.d("MainActivity", "id is $id")
                            Log.d("MainActivity", "name is $name")
                            Log.d("MainActivity", "version is $version")
                        }
                    }
                }
                eventType = xmlPullParser.next()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun parseXMLWithSAX(xmlData: String) {
        try {
            val saxParserFactory = SAXParserFactory.newInstance()
            val newSAXParser = saxParserFactory.newSAXParser().xmlReader
            val contentHandler = ContentHandler()

            //第一种方式
//            newSAXParser.parse(xmlData,contentHandler)

            //第二种方式
            newSAXParser.contentHandler = contentHandler
            newSAXParser.parse(InputSource(StringReader(xmlData)));
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    private fun parseJSONWithJSONObject(jsonData: String) {
        try {
            val jsonArray = JSONArray(jsonData)
            for (i in 0 until jsonArray.length()) {
                val jsonObject = jsonArray.getJSONObject(i)
                val id = jsonObject.getString("id")
                val name = jsonObject.getString("name")
                val version = jsonObject.getString("version")
                Log.d("MainActivity", "id is $id")
                Log.d("MainActivity", "name is $name")
                Log.d("MainActivity", "version is $version")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    private fun parseJSONWithGSON(jsonData: String) {
        val gson = Gson();
        val type = object : TypeToken<List<App>>() {}.type
        val fromJson = gson.fromJson<List<App>>(jsonData, type)
        for (app in fromJson) {
            Log.d("MainActivity", "id is ${app.id}")
            Log.d("MainActivity", "name is ${app.name}")
            Log.d("MainActivity", "version is ${app.version}")
        }
    }
}